﻿Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Windows
Imports Newtonsoft.Json

Public Class HttpClientBase

    Public ReadOnly Property Client As HttpClient

    Public Sub New()
        Client = New HttpClient()
        If Application.Current.Resources("Token") IsNot Nothing Then
            Client.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", Application.Current.Resources("Token").ToString())
        End If
        Client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json")
        Client.DefaultRequestHeaders.Accept.Clear()
        Client.DefaultRequestHeaders.AcceptCharset.ParseAdd("utf-8")
        Client.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json") With {.CharSet = "utf-8"})
        Client.BaseAddress = New Uri(NavigationData.SERVER_ACCESS_URL, UriKind.Absolute)
        Client.Timeout = TimeSpan.FromSeconds(30)
    End Sub

    'Public Sub New(MutipartFormData As Boolean)
    '    If MutipartFormData Then
    '        Client = New HttpClient()
    '        Client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "multipart/form-data")
    '        Client.DefaultRequestHeaders.Accept.Clear()
    '        Client.DefaultRequestHeaders.AcceptCharset.ParseAdd("utf-8")
    '        Client.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("multipart/form-data"))
    '        Client.BaseAddress = New Uri(NavigationData.SERVER_ACCESS_URL, UriKind.Absolute)
    '        Client.Timeout = TimeSpan.FromSeconds(30)
    '    End If
    'End Sub

    Public Async Function PostAsync(Of T)(data As Object, address As String) As Task(Of Result(Of T))
        Dim json = JsonConvert.SerializeObject(data, New JsonSerializerSettings With {
            .NullValueHandling = NullValueHandling.Ignore,
            .DateFormatHandling = DateFormatHandling.IsoDateFormat
        })
        Using content = New StringContent(json, Encoding.UTF8, "application/json")
            Using response = Await Client.PostAsync(address, content)
                If response.IsSuccessStatusCode Then
                    Dim responseContent = Await response.Content.ReadAsStringAsync()
                    Return JsonConvert.DeserializeObject(Of Result(Of T))(responseContent)
                Else
                    Dim errorContent = Await response.Content.ReadAsStringAsync()
                    Throw New HttpRequestException($"HTTP {response.StatusCode}: {errorContent}")
                End If
            End Using
        End Using
    End Function

    Public Async Function GetAsync(Of T)(address As String) As Task(Of Result(Of T))
        Using response = Await Client.GetAsync(address)
            If response.IsSuccessStatusCode Then
                Dim responseContent = Await response.Content.ReadAsStringAsync()
                Return JsonConvert.DeserializeObject(Of Result(Of T))(responseContent)
            Else
                Dim errorContent = Await response.Content.ReadAsStringAsync()
                Throw New HttpRequestException($"HTTP {response.StatusCode}: {errorContent}")
            End If
        End Using
    End Function

    Public Async Function PutAsync(Of T)(data As Object, address As String) As Task(Of Result(Of T))
        Dim json = JsonConvert.SerializeObject(data, New JsonSerializerSettings With {
            .NullValueHandling = NullValueHandling.Ignore,
            .DateFormatHandling = DateFormatHandling.IsoDateFormat
        })

        Using content = New StringContent(json, Encoding.UTF8, "application/json")
            Using response = Await Client.PutAsync(address, content)
                If response.IsSuccessStatusCode Then
                    Dim responseContent = Await response.Content.ReadAsStringAsync()
                    Return JsonConvert.DeserializeObject(Of Result(Of T))(responseContent)
                Else
                    Dim errorContent = Await response.Content.ReadAsStringAsync()
                    Throw New HttpRequestException($"HTTP {response.StatusCode}: {errorContent}")
                End If
            End Using
        End Using
    End Function

    Public Async Function DeleteAsync(Of T)(address As String) As Task(Of Result(Of T))
        Using response = Await Client.DeleteAsync(address)
            If response.IsSuccessStatusCode Then
                Dim responseContent = Await response.Content.ReadAsStringAsync()
                Return JsonConvert.DeserializeObject(Of Result(Of T))(responseContent)
            Else
                Dim errorContent = Await response.Content.ReadAsStringAsync()
                Throw New HttpRequestException($"HTTP {response.StatusCode}: {errorContent}")
            End If
        End Using
    End Function

End Class